package lock;

import java.util.concurrent.TimeUnit;

/**
 * @author fei
 * @date 2023/1/9 10:58
 * @description 死锁代码
 */
public class DeadLockDemo {

    public static void main(String[] args) {
        final Object objectA = new Object();
        final Object objectB = new Object();

        /**
         * 线程 A 持有锁 A，试图获取锁 B
         * 线程 B 持有锁 B，试图获取锁 A
         * 这样就会造成交叉获取，A 锁和 B 锁都没有释放，互相拿不到锁，导致死锁
         */

        new Thread(() -> {
            synchronized (objectA){
                // 这里一秒延迟是为了 B线程可以，先执行，然后这里再进行抢锁，导致死锁
                System.out.println(Thread.currentThread().getName() + "\t 自己持有 A 锁，希望获得 B 锁");
                try{ TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace(); }
                // 注意这里不是可重入锁，因为对象不一样
                synchronized (objectB){
                    System.out.println(Thread.currentThread().getName() + "\t 成功获得 B 锁");
                }
            }
        }, "A").start();

        new Thread(() -> {
            synchronized (objectB){
                System.out.println(Thread.currentThread().getName() + "\t 自己持有 B 锁，希望获得 A 锁");
                try{ TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace(); }
                synchronized (objectA){
                    System.out.println(Thread.currentThread().getName() + "\t 成功获得 A 锁");
                }
            }
        }, "A").start();
    }

}
